package apis

import (
	"encoding/json"
	"gluenet/pkg/gerrors"
	"gluenet/pkg/meta"
	"gluenet/pkg/ops/impl/helm"
	"gluenet/pkg/platform/glue"
	h "gluenet/pkg/platform/helm"
	v2 "gluenet/utils/rpc/v2/define"
)

const (
	ModuleDefault = "default"
	ModuleHelm    = "helm"

	KindApplication = "application"
	KindStrategy    = "strategy"
)

func BusAgentToAgent(a *v2.AgentInfo) (*meta.AgentInfo, *meta.AgentStatus) {
	i, s := meta.AgentInfo{}, meta.AgentStatus{}

	i.Guid = a.Guid
	i.Hostname = a.Hostname
	i.IP = a.IP
	i.MAC = a.MAC
	i.OS = a.OS
	i.Arch = a.Arch
	i.CPUs = a.CPUs
	i.MEM = a.MEM
	i.Area = a.Area

	s.Guid = a.Guid
	s.Status = a.Status
	s.Tags = a.Tags
	s.Services = a.Services
	//s.Instances = a.Instances

	return &i, &s
}

func DecodeConfigValue(values string, mod string) (interface{}, interface{}, error) {
	switch mod {
	case ModuleDefault:
		cfg := glue.Config{}
		if err := json.Unmarshal([]byte(values), &cfg); err != nil {
			return nil, nil, err
		}
		return &cfg, cfg.ConfigKind, nil
	case ModuleHelm:
		cfg := helm.Result{}
		if err := json.Unmarshal([]byte(values), &cfg); err != nil {
			return nil, nil, err
		}
		return &cfg, KindApplication, nil
	case PlatfromGluenets:
		cfg := glue.Config{}
		if err := json.Unmarshal([]byte(values), &cfg); err != nil {
			return nil, nil, err
		}
		return &cfg, cfg.ConfigKind, nil
	case PlatfromKubernetes:
		cfg := helm.Result{}
		if err := json.Unmarshal([]byte(values), &cfg); err != nil {
			return nil, nil, err
		}
		return &cfg, KindApplication, nil
	default:
		return nil, nil, gerrors.UnknownModuleError
	}
}

func DecodeInstanceValue(values string, mod string) (interface{}, interface{}, error) {
	switch mod {
	case ModuleDefault:
		ins := glue.Instance{}
		if err := json.Unmarshal([]byte(values), &ins); err != nil {
			return nil, nil, err
		}
		return &ins, ins.ConfigKind, nil
	case ModuleHelm:
		ins := h.Instance{}
		if err := json.Unmarshal([]byte(values), &ins); err != nil {
			return nil, nil, err
		}
		return &ins, KindApplication, nil
	case PlatfromGluenets:
		ins := glue.Instance{}
		if err := json.Unmarshal([]byte(values), &ins); err != nil {
			return nil, nil, err
		}
		return &ins, ins.ConfigKind, nil
	case PlatfromKubernetes:
		ins := h.Instance{}
		if err := json.Unmarshal([]byte(values), &ins); err != nil {
			return nil, nil, err
		}
		return &ins, KindApplication, nil
	default:
		return nil, nil, gerrors.UnknownModuleError
	}
}

func GetVersionAndDescribe(cfg *meta.Config) (interface{}, interface{}, error) {
	switch cfg.Platform {
	case PlatfromGluenets:
		var gcfg glue.Config
		if err := json.Unmarshal([]byte(cfg.ConfigValue), &gcfg); err != nil {
			return nil, nil, err
		}
		return gcfg.Version, gcfg.Describe, nil
	case PlatfromKubernetes:
		var hcfg = map[string]interface{}{}
		if err := json.Unmarshal([]byte(cfg.ConfigValue), &hcfg); err != nil {
			return nil, nil, err
		}
		hcfgi := hcfg["Chart"].(map[string]interface{})
		version, ok := hcfgi["version"]
		if !ok {
			version = ""
		}
		describe, ok := hcfgi["description"]
		if !ok {
			describe = ""
		}
		return version, describe, nil
	}
	return nil, nil, nil
}

func GetVersionAndDescribeFromInstance(ins *meta.Instance) (interface{}, interface{}, error) {
	switch ins.Platform {
	case PlatfromGluenets:
		var gins glue.Instance
		if err := json.Unmarshal([]byte(ins.InstanceValue), &gins); err != nil {
			return nil, nil, err
		}
		return gins.Version, gins.Describe, nil
	case PlatfromKubernetes:
		var hins h.Instance
		if err := json.Unmarshal([]byte(ins.InstanceValue), &hins); err != nil {
			return nil, nil, err
		}
		hcfgi := hins.Config.(map[string]interface{})["Chart"].(map[string]interface{})
		version, ok := hcfgi["version"]
		if !ok {
			version = ""
		}
		describe, ok := hcfgi["description"]
		if !ok {
			describe = ""
		}
		return version, describe, nil
	}
	return nil, nil, nil
}
